import AttributeUtil from "@/AttributeUtil";
import 数学 from "./数学";
import RandomUtil from "@/RandomUtil";

const 取属性 = AttributeUtil.getUnitAttribute;

export default class 单位函数 {
  static 取总耐力(目标: unit) {
    let v = 取属性(目标, true);
    let 耐力 = v?.strength ?? 0;
    耐力 += GetHeroStr(目标, false);
    耐力 += v.full_property ?? 0;
    耐力 *= 1 + (v.full_property_p ?? 0) + (v.strength_p ?? 0);
    return 耐力;
  }

  static 取总力量(目标: unit) {
    let v = 取属性(目标, true);
    let 力量 = v?.agility ?? 0;
    力量 += GetHeroAgi(目标, false);
    力量 += v.full_property ?? 0;
    力量 *= 1 + (v.full_property_p ?? 0) + (v.agility_p ?? 0);
    return 力量;
  }

  static 取总敏捷(目标: unit) {
    let v = 取属性(目标, true);
    let 敏捷 = v?.自定义敏捷 ?? 0;
    敏捷 += v.full_property ?? 0;
    敏捷 *= 1 + (v?.自定义敏捷百分比 ?? 0) + (v?.full_property_p ?? 0);
    return 敏捷;
  }

  static 取总智力(目标: unit) {
    let v = 取属性(目标, true);
    let 智力 = v?.自定义智力 ?? 0;
    智力 += v.full_property ?? 0;
    智力 *= 1 + (v?.自定义智力百分比 ?? 0) + (v?.full_property_p ?? 0);
    return 智力;
  }

  static 取总精神(目标: unit) {
    let v = 取属性(目标, true);
    let 精神 = v?.intelligence ?? 0;
    精神 += GetHeroInt(目标, false);
    精神 += v.full_property ?? 0;
    精神 *= 1 + (v.full_property_p ?? 0) + (v.intelligence_p ?? 0);
    return 精神;
  }

  static 取生命回复(目标: unit) {
    let v = 取属性(目标, true);
    let val =
      (GetUnitState(目标, UNIT_STATE_LIFE_REGEN) +
        (v.生命恢复 ?? 0) +
        单位函数.取总耐力(目标) * 0.05) *
      (1 + (v?.生命恢复增强 ?? 0));
    return R2I(val * 100) / 100;
  }

  static 取法力回复(目标: unit) {
    let v = 取属性(目标, true);
    let val =
      (GetUnitState(目标, UNIT_STATE_MANA_REGEN) +
        (v.法力恢复 ?? 0) +
        单位函数.取总智力(目标) * 0.03) *
      (1 + (v?.法力恢复增强 ?? 0));
    return R2I(val * 100) / 100;
  }

  static 取总护甲(目标: unit) {
    let v = 取属性(目标, true);
    return (
      ((v?.基础护甲 ?? 0) + (v?.附加护甲 ?? 0)) * (1 + (v?.护甲百分比 ?? 0)) ??
      0
    );
  }

  static 取总魔抗(目标: unit) {
    let v = 取属性(目标, true);
    return (
      ((v?.基础魔抗 ?? 0) + (v?.附加魔抗 ?? 0)) * (1 + (v?.魔抗百分比 ?? 0)) ??
      0
    );
  }

  static 取总闪避(目标) {
    let base = 0;
    let v = 取属性(目标);
    if (v != null) {
      base = v.基础闪避 ?? 0;
    }
    let 敏捷 = 单位函数.取总敏捷(目标);
    let 敏捷影响 = 数学.计算减益(
      敏捷,
      PHYSICAL_DODGE_PER_AGI,
      (GetHeroLevel(目标) + 10) / REDUTION_ATTENUATION
    );
    base += 敏捷影响;

    if (v != null) {
      for (let key in v) {
        if (key.includes("闪避")) {
          let doge = (v[key] as number) ?? 0;
          if (doge > base) {
            base = doge * (1 + base);
          } else {
            base = base + (1 + doge);
          }
        }
      }
    }
    return R2I(base * 100) / 100;
  }

  static 取物理暴击率(目标: unit) {
    let v = 取属性(目标, true);
    let 敏捷 = 单位函数.取总敏捷(目标);
    let 敏捷影响 = 数学.计算减益(
      敏捷,
      0.02,
      (GetHeroLevel(目标) + 10) / REDUTION_ATTENUATION
    );
    let 暴击 = v?.物理暴击机率 ?? 0;
    return R2I((敏捷影响 + 暴击) * 100) / 100;
  }

  static 取法术暴击率(目标: unit) {
    let v = 取属性(目标, true);
    let 智力 = 单位函数.取总智力(目标);
    let 智力影响 = 数学.计算减益(
      智力,
      0.02,
      (GetHeroLevel(目标) + 10) / REDUTION_ATTENUATION
    );
    let 暴击 = v?.法术暴击机率 ?? 0;
    return R2I((智力影响 + 暴击) * 100) / 100;
  }

  static 取物理暴击伤害(目标) {
    let v = 取属性(目标, true);
    let 力量 = 单位函数.取总力量(目标);
    let 力量影响 = 力量 * PHYSICAL_CRITICAL_DAMAGE_PER_STR;
    let 伤害 = v?.物理暴击伤害 ?? 1.5;
    return R2I((力量影响 + 伤害) * 100) / 100;
  }

  static 取法术暴击伤害(目标) {
    let v = 取属性(目标, true);
    let 智力 = 单位函数.取总智力(目标);
    let 智力影响 = 智力 * MAGIC_CRITICAL_DAMAGE_PER_INT;
    let 伤害 = v?.法术暴击伤害 ?? 1.5;
    return R2I((智力影响 + 伤害) * 100) / 100;
  }

  static 取物理伤害增强(目标: unit) {
    let v = 取属性(目标, true);
    let base = 1;
    base += (v?.物理伤害倍率 ?? 0) + (v?.全伤害倍率 ?? 0);
    return R2I(base * 100) / 100;
  }

  static 取法术伤害增强(目标: unit) {
    let v = 取属性(目标, true);
    let base = 1;
    base += (v?.法术伤害倍率 ?? 0) + (v?.全伤害倍率 ?? 0);
    return R2I(base * 100) / 100;
  }

  static 取法强(目标: unit) {
    let v = 取属性(目标, true);
    let base = 0;
    base += (v?.法术强度 ?? 0) * (1 + (v?.法术强度百分比 ?? 0));
    return R2I(base);
  }

  static 取攻击(目标: unit) {
    return RandomUtil.nextReal(
      GetUnitState(目标, UnitStateDamageMix),
      GetUnitState(目标, UnitStateDamageMax)
    );
  }

  static 取固定攻击(目标: unit) {
    let atk =
      (GetUnitState(目标, UnitStateDamageMix) +
        GetUnitState(目标, UnitStateDamageMax)) /
      2;
    return R2I(atk);
  }

  static 取物理伤害减免(目标: unit) {
    let v = 取属性(目标, true);
    let base = 0;
    base += (v?.物理伤害减免 ?? 0) + (v?.全伤害减免 ?? 0);
    return R2I(base * 100) / 100;
  }

  static 取法术伤害减免(目标: unit) {
    let v = 取属性(目标, true);
    let base = 0;
    base += (v?.法术伤害减免 ?? 0) + (v?.全伤害减免 ?? 0);
    return R2I(base * 100) / 100;
  }

  static 取命中率(目标: unit) {
    let v = 取属性(目标, true);
    return v?.命中 ?? 0;
  }

  static 取物理吸血(目标: unit) {
    let v = 取属性(目标, true);
    return v?.物理吸血 ?? 0;
  }

  static 取法术吸血(目标: unit) {
    let v = 取属性(目标, true);
    return v?.法术吸血 ?? 0;
  }

  static 取冷却降低(目标: unit) {
    let v = 取属性(目标, true);
    let base = 1;
    if (v != null) {
      for (let key in v) {
        if (key.includes("冷却") && typeof v[key] == "number") {
          base *= 1 - (v[key] as number);
        }
      }
    }
    return R2I(base * 100) / 100;
  }

  static 取AOE伤害减免(目标: unit) {
    let v = 取属性(目标, true);
    return v?.AOE伤害减免 ?? 0;
  }

  static 取治疗增强(目标: unit) {
    let v = 取属性(目标, true);
    return v?.治疗增强 ?? 0;
  }
}
